package com.itheima.sfbx.insurance.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.sfbx.framework.commons.constant.basic.SuperConstant;
import com.itheima.sfbx.framework.commons.exception.ProjectException;
import com.itheima.sfbx.framework.commons.utils.BeanConv;
import com.itheima.sfbx.insurance.dto.ConditionVO;
import com.itheima.sfbx.insurance.enums.ConditionEnum;
import com.itheima.sfbx.insurance.enums.SafeguardEnum;
import com.itheima.sfbx.insurance.mapper.ConditionMapper;
import com.itheima.sfbx.insurance.pojo.CategoryCondition;
import com.itheima.sfbx.insurance.pojo.Condition;
import com.itheima.sfbx.insurance.pojo.InsuranceCondition;
import com.itheima.sfbx.insurance.service.ICategoryConditionService;
import com.itheima.sfbx.insurance.service.IConditionService;
import com.itheima.sfbx.insurance.service.IInsuranceConditionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
/**
 * @Description：筛选项服务实现类
 */
@Slf4j
@Service
public class ConditionServiceImpl extends ServiceImpl<ConditionMapper, Condition> implements IConditionService {

    @Autowired
    private ICategoryConditionService categoryConditionService;

    @Autowired
    private IInsuranceConditionService insuranceConditionService;


    @Override
    public Page<ConditionVO> findPage(ConditionVO conditionVO, int pageNum, int pageSize) {
        Page<Condition> page = this.lambdaQuery()
                .eq(StringUtils.isNotBlank(conditionVO.getConditionKey()), Condition::getConditionKey, conditionVO.getConditionKey())
                .like(StringUtils.isNotBlank(conditionVO.getConditionKeyName()), Condition::getConditionKeyName, conditionVO.getConditionKeyName())
                .eq(StringUtils.isNotBlank(conditionVO.getDataState()), Condition::getDataState, conditionVO.getDataState())
                .page(new Page<>(pageNum, pageSize));

        return BeanConv.toPage(page, ConditionVO.class);
    }

    @Override
    public ConditionVO findById(String conditionId) {
        //TODO
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ConditionVO save(ConditionVO conditionVO) {
        // 检查条件键是否已存在
        Integer count = this.lambdaQuery()
                .eq(Condition::getConditionKey, conditionVO.getConditionKey())
                .eq(Condition::getDataState, SuperConstant.DATA_STATE_0)
                .count();
        if (count > 0){
            // 如果条件键已存在，则记录错误日志并抛出异常
            log.error("新增筛选项失败, 因为key已经存在:{}", conditionVO.getConditionKey());
            throw new ProjectException(ConditionEnum.SAVE_FAIL);
        }
        // 检查条件键名称是否已存在
        count = this.lambdaQuery()
                .eq(Condition::getConditionKeyName, conditionVO.getConditionKeyName())
                .eq(Condition::getDataState, SuperConstant.DATA_STATE_0)
                .count();
        if (count > 0){
            // 如果条件键名称已存在，则记录错误日志并抛出异常
            log.error("新增筛选项失败, 因为keyName已经存在:{}", conditionVO.getConditionKeyName());
            throw new ProjectException(ConditionEnum.SAVE_FAIL);
        }
        // 将条件VO对象转换为条件实体对象
        Condition bean = BeanConv.toBean(conditionVO, Condition.class);
        // 保存条件实体对象
        this.save(bean);
        // 将保存后的条件实体对象转换为条件VO对象并返回
        return BeanConv.toBean(bean, ConditionVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean update(ConditionVO conditionVO) {
        // 根据ID获取条件对象
        Condition bean = this.getById(conditionVO.getId());
        // 检查对象是否存在，如果不存在则记录错误日志并抛出异常
        if(bean == null){
            log.error("数据不存在:{}", conditionVO.getId());
            throw new ProjectException(SafeguardEnum.UPDATE_FAIL);
        }

        // 检查条件键是否已存在于其他记录中，以确保唯一性
        Integer count = this.lambdaQuery()
                .eq(Condition::getConditionKey, conditionVO.getConditionKey())
                .ne(Condition::getId, conditionVO.getId())
                .count();
        // 如果发现重复的条件键，记录错误日志并抛出异常
        if(count > 0){
            log.error("修改筛选项失败, 因为key已经存在:{}", conditionVO.getConditionKey());
            throw new ProjectException(SafeguardEnum.UPDATE_FAIL);
        }

        // 检查条件键是否在分类条件表中使用，以确保没有关联关系
        Integer count1 = categoryConditionService.lambdaQuery()
                .eq(CategoryCondition::getConditionKey, conditionVO.getConditionKey())
                .count();
        // 检查条件键是否在保险条件表中使用，以确保没有关联关系
        Integer count2 = insuranceConditionService.lambdaQuery()
                .eq(InsuranceCondition::getConditionKey, conditionVO.getConditionKey())
                .count();
        // 如果发现有关联关系，记录错误日志并抛出异常
        if(count1 > 0 || count2 > 0){
            log.error("修改筛选项失败, 有关联关系:{}", conditionVO.getConditionKey());
            throw new ProjectException(SafeguardEnum.UPDATE_FAIL);
        }

        // 更新条件对象，返回更新结果
        return this.updateById(BeanConv.toBean(conditionVO, Condition.class));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(String[] checkedIds) {
        // 初始化结果变量为false
        boolean result = false;
        // 遍历选中的ID列表
        for (String id : checkedIds) {
            // 根据ID获取保障项实体
            Condition bean = this.getById(id);
            // 检查保障项实体是否存在
            if(bean == null){
                // 如果不存在，记录错误日志并抛出异常
                log.error("数据不存在:{}", id);
                throw new ProjectException(SafeguardEnum.DEL_FAIL);
            }
            // 检查条件键是否在分类条件表中使用，以确保没有关联关系
            Integer count1 = categoryConditionService.lambdaQuery()
                    .eq(CategoryCondition::getConditionKey, bean.getConditionKey())
                    .count();
            // 检查条件键是否在保险条件表中使用，以确保没有关联关系
            Integer count2 = insuranceConditionService.lambdaQuery()
                    .eq(InsuranceCondition::getConditionKey, bean.getConditionKey())
                    .count();
            // 如果发现有关联关系，记录错误日志并抛出异常
            if(count1 > 0 || count2 > 0){
                log.error("修改筛选项失败, 有关联关系:{}", bean.getConditionKey());
                throw new ProjectException(SafeguardEnum.UPDATE_FAIL);
            }
            // 删除当前遍历的保障项实体
            result = this.removeById(id);
        }
        // 返回删除结果
        return result;
    }

    @Override
    public List<ConditionVO> findList(ConditionVO conditionVO) {
        //TODO
        return null;
    }

    @Override
    public List<ConditionVO> findInConditionKeys(List<String> conditionKeys) {
        //TODO
        return null;
    }
}
